package com.tianji.learning.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tianji.api.cache.CategoryCache;
import com.tianji.api.client.course.CatalogueClient;
import com.tianji.api.client.course.CategoryClient;
import com.tianji.api.client.course.CourseClient;
import com.tianji.api.client.search.SearchClient;
import com.tianji.api.client.user.UserClient;
import com.tianji.api.dto.course.CataSimpleInfoDTO;
import com.tianji.api.dto.course.CourseFullInfoDTO;
import com.tianji.api.dto.course.CourseSimpleInfoDTO;
import com.tianji.api.dto.user.UserDTO;
import com.tianji.common.domain.dto.PageDTO;
import com.tianji.common.exceptions.BadRequestException;
import com.tianji.common.exceptions.BizIllegalException;
import com.tianji.common.exceptions.DbException;
import com.tianji.common.utils.*;
import com.tianji.learning.domin.dto.QuestionFormDTO;
import com.tianji.learning.domin.po.InteractionQuestion;
import com.tianji.learning.domin.po.InteractionReply;
import com.tianji.learning.domin.vo.QuestionAdminVO;
import com.tianji.learning.domin.vo.QuestionVO;
import com.tianji.learning.mapper.InteractionQuestionMapper;
import com.tianji.learning.query.QuestionAdminPageQuery;
import com.tianji.learning.query.QuestionPageQuery;
import com.tianji.learning.service.IInteractionQuestionService;
import com.tianji.learning.service.IInteractionReplyService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 互动提问的问题表 服务实现类
 * </p>
 *
 * @author author
 * @since 2023-09-08
 */
@Service
@RequiredArgsConstructor
public class InteractionQuestionServiceImpl extends ServiceImpl<InteractionQuestionMapper, InteractionQuestion> implements IInteractionQuestionService {

    private final IInteractionReplyService interactionReplyService;
    private final UserClient userClient;
    private final SearchClient searchClient;
    private final CourseClient courseClient;
    private final CatalogueClient catalogueClient;
    private final CategoryClient categoryClient;
    private final CategoryCache categoryCache;

    @Override
    public void addQuestions(QuestionFormDTO dto) {
        //获取当前提问用户
        Long userId = UserContext.getUser();
        //dto转po
        InteractionQuestion interactionQuestion = BeanUtils.copyBean(dto, InteractionQuestion.class);
        interactionQuestion.setUserId(userId);
        //保存数据库
        boolean isSave = save(interactionQuestion);
        if (!isSave) {
            throw new DbException("保存问题到数据库失败");
        }
    }

    @Override
    public void updateQuestion(Long id, QuestionFormDTO dto) {
        //检查参数
        if (id == null || StringUtils.isBlank(dto.getDescription()) || StringUtils.isBlank(dto.getTitle()) || dto.getAnonymity() == null) {
            throw new BadRequestException("参数异常");
        }
        //根据id查数据库
        InteractionQuestion interactionQuestion = getById(id);


        //设置参数
        interactionQuestion.setDescription(dto.getDescription());
        interactionQuestion.setTitle(dto.getTitle());
        interactionQuestion.setAnonymity(dto.getAnonymity());
        //确认是否是当前用户的问题
        Long userId = UserContext.getUser();
        if (userId.equals(interactionQuestion.getUserId())) {
            throw new BadRequestException("更新问题权限不足");
        }
        //更新
        updateById(interactionQuestion);
    }

    @Override
    public QuestionVO queryQuestionById(Long id) {

        //校验参数
        if (id == null) {
            throw new BadRequestException("查询问题详情：id为空");
        }
        //查询问题表 条件 主键id 是否隐藏
        InteractionQuestion interactionQuestion = lambdaQuery().eq(InteractionQuestion::getId, id).eq(InteractionQuestion::getHidden, false).one();
        //封装VO返回
        QuestionVO questionVO = BeanUtils.copyBean(interactionQuestion, QuestionVO.class);
        questionVO.setUserId(null);
        if (!interactionQuestion.getAnonymity()) {
            UserDTO userDTO = userClient.queryUserById(interactionQuestion.getUserId());
            if (userDTO != null) {
                questionVO.setUserIcon(userDTO.getIcon());
                questionVO.setUserName(userDTO.getName());
            }

        }
        return questionVO;
    }

    @Override
    public void deleteQuestionById(Long id) {
        //校验参数
        if (id == null) {
            throw new BadRequestException("非法参数");
        }
        //获取当前登录用户id
        Long userId = UserContext.getUser();
        //根据用户id删除问题
        boolean remove = remove(Wrappers.<InteractionQuestion>lambdaQuery().eq(InteractionQuestion::getUserId, userId).eq(InteractionQuestion::getId, id));
        if (!remove) {
            throw new DbException("deleteQuestionById==>删除失败");
        }

    }

    @Override
    public PageDTO<QuestionAdminVO> queryQuestionPageAdmin(QuestionAdminPageQuery query) {

        //调用搜索服务 根据课程名称获取课程Id
        String courseName = query.getCourseName();
        List<Long> coursesIds = null;
        if (courseName != null) {
            coursesIds = searchClient.queryCoursesIdByName(courseName);
        }
        //查询问题表 如果请求参数不为空 加入条件 按照创建时间分页
        Page<InteractionQuestion> page = lambdaQuery()
                .eq(query.getStatus() != null, InteractionQuestion::getStatus, query.getStatus())
                .in(CollUtils.isNotEmpty(coursesIds), InteractionQuestion::getCourseId, coursesIds)
                .between(query.getBeginTime() != null && query.getEndTime() != null, InteractionQuestion::getCreateTime, query.getBeginTime(), query.getEndTime())
                .page(query.toMpPage("create_time", false));
        List<InteractionQuestion> records = page.getRecords();
        if (CollUtils.isEmpty(records)) {
            return PageDTO.of(page, CollUtils.emptyList());
        }

        Set<Long> uIds = new HashSet<>();
        Set<Long> courseIds = new HashSet<>();
        Set<Long> chapterAndSectionIds = new HashSet<>();

        for (InteractionQuestion record : records) {
            uIds.add(record.getUserId());
            courseIds.add(record.getCourseId());
            chapterAndSectionIds.add(record.getChapterId());
            chapterAndSectionIds.add(record.getSectionId());
        }
        //调用用户服务 获取用户名

        List<UserDTO> UserDTOs = userClient.queryUserByIds(uIds);
        Map<Long, String> userNameMap = UserDTOs.stream().collect(Collectors.toMap(UserDTO::getId, UserDTO::getName));
        if (CollUtils.isEmpty(userNameMap)) {
            throw new BizIllegalException("获取用户异常");
        }
        //调用课程服务 获取课程名

        List<CourseSimpleInfoDTO> courseInfo = courseClient.getSimpleInfoList(courseIds);
        if (CollUtils.isEmpty(courseInfo)) {
            throw new BizIllegalException("获取课程异常");
        }
        Map<Long, CourseSimpleInfoDTO> courseNameMap = courseInfo.stream().collect(Collectors.toMap(CourseSimpleInfoDTO::getId, o -> o));
        //调用课程服务 获取章节名 获取小节名称

        List<CataSimpleInfoDTO> cataSimpleInfoDTOS = catalogueClient.batchQueryCatalogue(chapterAndSectionIds);
        Map<Long, String> cataSimpleInfoMap = cataSimpleInfoDTOS.stream().collect(Collectors.toMap(CataSimpleInfoDTO::getId, CataSimpleInfoDTO::getName));
        //封装VO返回
        List<QuestionAdminVO> questionAdminVOS = new ArrayList<>();

        for (InteractionQuestion interactionQuestion : records) {
            QuestionAdminVO questionAdminVO = BeanUtils.copyBean(interactionQuestion, QuestionAdminVO.class);
            String userName = userNameMap.get(interactionQuestion.getUserId());

            if (userName != null) {

                questionAdminVO.setUserName(userName);
            }

            CourseSimpleInfoDTO courseSimpleInfoDTO = courseNameMap.get(interactionQuestion.getCourseId());

            if (courseSimpleInfoDTO != null) {
                questionAdminVO.setCourseName(courseSimpleInfoDTO.getName());
                List<Long> categoryIds = courseSimpleInfoDTO.getCategoryIds();
                String categoryNames = categoryCache.getCategoryNames(categoryIds);
                questionAdminVO.setCategoryName(categoryNames);
            }
            String chapterName = cataSimpleInfoMap.get(interactionQuestion.getChapterId());
            questionAdminVO.setChapterName(chapterName);
            String sectionName = cataSimpleInfoMap.get(interactionQuestion.getSectionId());
            questionAdminVO.setSectionName(sectionName);
            questionAdminVOS.add(questionAdminVO);
        }
        return PageDTO.of(page, questionAdminVOS);
    }

    @Override
    public void updateHiddenStatus(Long id, Boolean hidden) {
        if (id == null || hidden == null) {
            throw new BadRequestException("参数异常");
        }
        boolean isUpdate = lambdaUpdate().eq(InteractionQuestion::getId, id).set(InteractionQuestion::getHidden, hidden).update();
        if (BooleanUtils.isFalse(!isUpdate)) {
            throw new DbException("Hidden字段更新失败");
        }
    }

    @Override
    public QuestionAdminVO showDescription(Long id) {
        if (id == null) {
            throw new BadRequestException("参数异常");
        }
        //查询问题表 条件根据id
        InteractionQuestion interactionQuestion = lambdaQuery().eq(InteractionQuestion::getId, id).one();
        if (interactionQuestion == null) {
            return new QuestionAdminVO();
        }
        // 调用课程服务获取课程信息
        CourseFullInfoDTO courseInfo = courseClient.getCourseInfoById(interactionQuestion.getCourseId(), false, true);

        //调用用户服务 批量获取用户
        List<Long> userIds = courseInfo.getTeacherIds();
        userIds.add(interactionQuestion.getUserId());
        List<UserDTO> userDTOS = userClient.queryUserByIds(userIds);
        //调用课程服务 获取章节名 获取小节名称
        List<CataSimpleInfoDTO> cataSimpleInfoDTOS = catalogueClient.batchQueryCatalogue(List.of(interactionQuestion.getChapterId(), interactionQuestion.getSectionId()));
        Map<Long, String> cataSimpleInfoDTOMap = cataSimpleInfoDTOS.stream().collect(Collectors.toMap(CataSimpleInfoDTO::getId, CataSimpleInfoDTO::getName));
        //调用课程服务 课程名
        //封装VO返回
        QuestionAdminVO questionAdminVO = BeanUtils.copyBean(interactionQuestion, QuestionAdminVO.class);
        String chapterName = cataSimpleInfoDTOMap.get(interactionQuestion.getChapterId());
        String sectionName = cataSimpleInfoDTOMap.get(interactionQuestion.getSectionId());
        questionAdminVO.setChapterName(chapterName);
        questionAdminVO.setSectionName(sectionName);
        questionAdminVO.setCourseName(courseInfo.getName());
        String categoryNames = categoryCache.getCategoryNames(courseInfo.getCategoryIds());
        questionAdminVO.setCategoryName(categoryNames);
        for (UserDTO userDTO : userDTOS) {

            if (userDTO.getType() == 3) {

                questionAdminVO.setTeacherName(userDTO.getName());
            }
            if (userDTO.getType() == 2) {
                questionAdminVO.setUserName(userDTO.getName());
            }
        }
        return questionAdminVO;
    }


    @Override
    public PageDTO<QuestionVO> queryQuestionPage(QuestionPageQuery query) {

        //校验 参数courseId

        if (query.getCourseId() == null || query.getOnlyMine() == null) {
            throw new BadRequestException("参数异常");
        }
        //获取用户id
        Long userId = UserContext.getUser();
        //查询问题表 条件 courseId onlyMine为true是加入用户id sectionId不为null时加入条件 hidden为false 根据创建时间降序
        Page<InteractionQuestion> page = lambdaQuery()
                .select(InteractionQuestion.class, tableFieldInfo -> !tableFieldInfo.getProperty().equals("description"))
                .eq(InteractionQuestion::getCourseId, query.getCourseId())
                .eq(query.getOnlyMine(), InteractionQuestion::getUserId, userId)
                .eq(query.getSectionId() != null, InteractionQuestion::getSectionId, query.getSectionId())
                .eq(InteractionQuestion::getHidden, false)
                .page(query.toMpPageDefaultSortByCreateTimeDesc());

        List<InteractionQuestion> interactionQuestions = page.getRecords();
        if (CollectionUtils.isEmpty(interactionQuestions)) {
            return PageDTO.empty(page);
        }
        //1578558664933920356

        //查询回答表 获取最近一次回答id
        List<Long> latestAnswerIds = interactionQuestions.stream().map(InteractionQuestion::getLatestAnswerId).filter(Objects::nonNull).collect(Collectors.toList());
        //收集用户id
        List<Long> questionUserIds = interactionQuestions.stream().filter(o -> !o.getAnonymity()).map(InteractionQuestion::getUserId).collect(Collectors.toList());
        Set<Long> userIds = new HashSet<>(questionUserIds);

        Map<Long, InteractionReply> replyMap = null;
        if (CollUtils.isNotEmpty(latestAnswerIds)) {
            List<InteractionReply> interactionReplies = interactionReplyService.list(Wrappers.<InteractionReply>lambdaQuery().in(InteractionReply::getId, latestAnswerIds).eq(InteractionReply::getHidden, false));
            //回答表的用户id集合
            for (InteractionReply interactionReply : interactionReplies) {
                if (!interactionReply.getAnonymity()) {
                    userIds.add(interactionReply.getUserId());
                }
            }
            replyMap = interactionReplies.stream().collect(Collectors.toMap(InteractionReply::getId, o -> o));
        }

        //远程调用用户服务 获取用户信息 批量
        Map<Long, UserDTO> userDTOMap = userClient.queryUserByIds(userIds).stream().collect(Collectors.toMap(UserDTO::getId, o -> o));
        //封装VO返回
        List<QuestionVO> questionVOS = new ArrayList<>();


        for (InteractionQuestion interactionQuestion : interactionQuestions) {


            QuestionVO questionVO = BeanUtils.copyBean(interactionQuestion, QuestionVO.class);
            //当前登录用户信息
            if (!questionVO.getAnonymity()) {
                UserDTO userDTO = userDTOMap.get(interactionQuestion.getUserId());
                if (userDTO != null) {
                    questionVO.setUserName(userDTO.getName());
                    questionVO.setUserIcon(userDTO.getIcon());
                }
            }

            //回答表信息
            if (interactionQuestion.getLatestAnswerId() != null) {
                if (CollUtils.isNotEmpty(replyMap)) {
                    InteractionReply interactionReply = replyMap.get(interactionQuestion.getLatestAnswerId());
                    //回答用户信息
                    if (!interactionReply.getAnonymity()) {
                        UserDTO ReplyUser = userDTOMap.get(interactionReply.getUserId());
                        questionVO.setLatestReplyUser(ReplyUser.getName());
                    }

                    questionVO.setLatestReplyContent(interactionReply.getContent());
                    //获取回答者
                    Long replyUserId = interactionReply.getUserId();
                    UserDTO replyUserDTO = userDTOMap.get(replyUserId);

                    questionVO.setLatestReplyUser(replyUserDTO.getName());
                }
            }

            questionVOS.add(questionVO);

        }

        return PageDTO.of(page, questionVOS);
    }
}
